# （1）我是quant林，早年供职于上海的量化私募，后于2017年推出的免费Python期货CTP接口开源框架，采用GPLV3开源协议，简单易学，
# 适合学习入门和拓展开发，就在1.0版发布后不久，我的vnapi 1.0（当时不叫vnapi）就遭受了非法金融经营者用1.2万字连载诽谤文的诋毁攻击，
# 他们甚至在诽谤文下方还放上他们自己的涉及非法金融开源软件的广告。
# 从那次诋毁到现在2.10版的重新推出已过了快7年，人生又有几个7年？
# 当初我作为技术创业者从未遇到类似的情况，不知如何应对，2017年7月我离开上海去了重庆，在重庆
# 写出了virtualapi仿真回测（盛立版、CTP版、通联沪深A股Level2版）、vntrader6框架雏形、kucps专业投资软件的代码，
# 每天开发工作完毕，就去万州的小巷点一份小火锅和啤酒，这是我最难忘的回忆，2019年我又回到了上海，
# 在最近刀郎事件发生后，我开始怀疑我当初离开上海的想法和刀郎的想法是一样的。
# 由于非法金融具有伪装性和渗透性，前几年利用开源开源旗号不断侵蚀我国合规金融市场，某币圈网红公开宣传非法金融，
# 其带有非法金融交易功能的软件甚至短暂的上了某期货公司官网，后他们又于2021年11月被上海证监局调查。
# 在过去7年中，我在打击非法金融的战线上贡献了自己的力量，付出了大量时间和精力的代价，说不清楚这样做是为了自救，
# 还是别的原因，但我忠心的希望金融从业者们牢记合规底线，勿给非法金融可乘之机。
# 为记住那段历史，本次发布的vnapi2.10 期货CTP接口行情库底层代码，正是源于2017年4月的1.0开源版本的稍作整理，已升级到最新的CTP版本，
# 1.0版就是被诋毁造谣的那个版本，vnapi改名前的1.0 版本曾被北京大学出版社《python3.x全栈开发》收录并重点介绍，
# 现在vnapi2.0作为一款Python CTP接口的框架，和当初1.0一样，是基于Ctypes技术，简单易学，主要目的是为了为开发者
# 提供一个通俗易懂的python后端开源框架，并非为了提供一款面面俱到的商业产品，适合入门学习和在此基础上继续拓展开发。
# 我还采用PyQt技术开发为前端开发的 vntrader6客户端（https://www.vnpy.cn）， 基于我开发的vnapi的另一个回调版本，
# 面向的是专业机构客户，VNTrader系列可以说在vnapi 1.0后端框架技术上迭代产生的，
# 当初的1.0，和今天发布的2.0，以及VNTrader、Virtualapi产品均属于我和上海量贝软件的原创产品，
# 我于2014年还获得基于AR增强现实技术的国家发明专利一项。
# 我另有正在申请3项量化交易发明专利，这些技术已授予用于上海量贝作为技术积累可用于商业技术开发。
# 也希望谣言发布者们知晓，靠谣言诋毁一个执迷于技术的程序员和技术创业者是不可能成功的。
# 承载着7年的维权经历与梦想，引来了vnapi2.10版本的发布，这个产品定位是作抛砖引玉之用，适合用户学习Python量化和扩展功能，
# 而非堆砌功能，请各位以宽容的眼光去对待他。
# （2）vnapi 遵循 开源协议GPL v3
# 简单得说：对基于GPL v3协议的源代码，若个人或机构仅仅是自己使用，则可以闭源。
# 若基于该开源代码，开发出程序或衍生产品用于商业行为则也需开源。
# 官方网站：http://www.vnpy.cn

# -*- coding=utf-8 -*-
import ctypes

from vnapictptdType import *
import vnapictptdType
import time
class vnapictptd(object):
    def __init__(self):
        self.vntd = CDLL('vnapictptd.dll')

        self.fReqUserLogin = self.vntd.ReqUserLogin
        self.fReqUserLogin.argtypes = []
        self.fReqUserLogin.restype = c_int32

        self.fInsertOrder = self.vntd.InsertOrder
        self.fInsertOrder.argtypes = [c_char_p, c_char, c_char, c_char, c_double, c_int32]
        self.fInsertOrder.restype = c_int32

        self.fInsertOrderByRate = self.vntd.InsertOrderByRate
        self.fInsertOrderByRate.argtypes = [c_char_p, c_char, c_char, c_char, c_double, c_double, c_int32, c_int32]
        self.fInsertOrderByRate.restype = c_int32

        self.fDeleteOrder = self.vntd.DeleteOrder
        self.fDeleteOrder.argtypes = [c_char_p, c_int32]
        self.fDeleteOrder.restype = c_int32

        self.fQryTradedVol = self.vntd.QryTradedVol
        self.fQryTradedVol.argtypes = [c_int32]
        self.fQryTradedVol.restype = c_int32

        self.fQryPosition = self.vntd.QryPosition
        self.fQryPosition.argtypes = [c_char_p, c_int32]
        self.fQryPosition.restype = c_int32

        self.fQryPositionList = self.vntd.QryPositionList
        self.fQryPositionList.argtypes = [c_int32]
        self.fQryPositionList.restype = c_void_p

        self.fQryBalance = self.vntd.QryBalance
        self.fQryBalance.argtypes = [c_bool]
        self.fQryBalance.restype = c_double

        self.fQryAvailable = self.vntd.QryAvailable
        self.fQryAvailable.argtypes = []
        self.fQryAvailable.restype = c_double

        self.fSetShowPosition = self.vntd.SetShowPosition
        self.fSetShowPosition.argtypes = [c_bool]
        self.fSetShowPosition.restype = c_void_p

        self.fReqQryInstrumentMarginRate = self.vntd.ReqQryInstrumentMarginRate
        self.fReqQryInstrumentMarginRate.argtypes = [c_char_p, c_int32]
        self.fReqQryInstrumentMarginRate.restype = c_double

        self.fQryUnderlyingMultiple = self.vntd.QryUnderlyingMultiple
        self.fQryUnderlyingMultiple.argtypes = [c_char_p]
        self.fQryUnderlyingMultiple.restype = c_double

        #self.fQryQueryMaxOrderVolume = self.vntd.QryQueryMaxOrderVolume
        #self.fQryQueryMaxOrderVolume.argtypes = [c_char_p, c_char_p, c_char_p, c_char, c_char, c_char, c_int32]
        #self.fQryQueryMaxOrderVolume.restype = c_int32

        self.fOnCmd = self.vntd.OnCmd
        self.fOnCmd.argtypes = []
        self.fOnCmd.restype = c_int32

        self.fGetCmd = self.vntd.GetCmd
        self.fGetCmd.argtypes = []
        self.fGetCmd.restype = c_int32

        self.fGetCmdContent = self.vntd.GetCmdContent
        self.fGetCmdContent.argtypes = []
        self.fGetCmdContent.restype = c_char_p

        self.fGetCmdContent_Order = self.vntd.GetCmdContent_Order
        self.fGetCmdContent_Order.argtypes = []
        self.fGetCmdContent_Order.restype = c_void_p

        self.fGetCmdContent_Settlement = self.vntd.GetCmdContent_Settlement
        self.fGetCmdContent_Settlement.argtypes = []
        self.fGetCmdContent_Settlement.restype = c_void_p

        self.fGetCmdContent_Error = self.vntd.GetCmdContent_Error
        self.fGetCmdContent_Error.argtypes = []
        self.fGetCmdContent_Error.restype = c_void_p

        self.fGetCmdContent_LoginScuess = self.vntd.GetCmdContent_LoginScuess
        self.fGetCmdContent_LoginScuess.argtypes = []
        self.fGetCmdContent_LoginScuess.restype = c_int32

        self.fGetCmdContent_Connected = self.vntd.GetCmdContent_Connected
        self.fGetCmdContent_Connected.argtypes = []
        self.fGetCmdContent_Connected.restype = c_int32

        self.fGetCmdContent_ProductGroupMargin = self.vntd.GetCmdContent_ProductGroupMargin
        self.fGetCmdContent_ProductGroupMargin.argtypes = []
        self.fGetCmdContent_ProductGroupMargin.restype = c_int32

        self.fGetCmdContent_CommissionRate = self.vntd.GetCmdContent_CommissionRate
        self.fGetCmdContent_CommissionRate.argtypes = []
        self.fGetCmdContent_CommissionRate.restype = c_int32

    def ReqUserLogin(self):
        return self.fReqUserLogin()

    def InsertOrder(self, instrumentID, direction, offsetFlag, priceType, price, num): #c_char
        return self.fInsertOrder(bytes(instrumentID, encoding="gb2312"),
                                 bytes(direction, encoding="gb2312"),
                                 bytes(offsetFlag, encoding="gb2312"),
                                 bytes(priceType, encoding="gb2312"),
                                 c_double(price), c_int32(num))
    #cast(instrumentID, c_char_p)
    #bytes(InstrumentID, encoding="utf-8")
    # 根据资金比例下单
    def InsertOrderByRate(self, instrumentID, direction, offsetFlag, priceType, price, rate, BalanceType, multiplier):
        return self.fInsertOrderByRate(bytes(instrumentID, encoding="gb2312"),
                                       bytes(direction, encoding="gb2312"),
                                       bytes(offsetFlag, encoding="gb2312"),
                                       bytes(priceType, encoding="gb2312"),
                                       c_double(price),
                                       rate,
                                       BalanceType,
                                       multiplier)

    def DeleteOrder(self, instrumentID, orderRef):
        return self.fDeleteOrder(bytes(instrumentID, encoding="gb2312"),
                                 orderRef)

    def QryTradedVol(self, orderRef):
        return self.fQryTradedVol(orderRef)

    # 查询品种持仓
    def QryPosition(self, instrumentID, positiontype):
        return self.fQryPosition(bytes(instrumentID, encoding="gb2312"), positiontype)

    # 查询持仓列表
    def QryPositionList(self, orderRef):
        return self.fQryPositionList(orderRef)

    # 查询权益   BalanceType=True动态权益    BalanceType=False静态权益
    def QryBalance(self, BalanceType):
        return self.fQryBalance(BalanceType)

    # 查询可用资金
    def QryAvailable(self):
        return self.fQryAvailable()

    # 设置更新持仓数据时显示,仅对控制台有效
    def SetShowPosition(self, showstate):
        self.fSetShowPosition(showstate)

    # 查询保证金比例
    def ReqQryInstrumentMarginRate(self, instrumentID, Type):
        return self.fReqQryInstrumentMarginRate(bytes(instrumentID, encoding="gb2312"), Type)

    # 查询合约乘数
    def QryUnderlyingMultiple(self, instrumentID):
        return self.fQryUnderlyingMultiple(bytes(instrumentID, encoding="gb2312"))

    # 查询
    '''
    def QryQueryMaxOrderVolume(self, BrokerID, InvestorID, instrumentID, Direction, OffsetFlag, HedgeFlag, MaxVolume):
        return self.fQryQueryMaxOrderVolume( bytes(BrokerID, encoding="gb2312"),
                                             bytes(InvestorID, encoding="gb2312"),
                                             bytes(instrumentID, encoding="gb2312"),
                                             bytes(Direction, encoding="gb2312"),
                                             bytes(OffsetFlag, encoding="gb2312"),
                                             bytes(HedgeFlag, encoding="gb2312"),MaxVolume)
    '''

    def OnCmd(self):
        return self.fOnCmd()

    def GetCmd(self):
        return (self.fGetCmd(), self.fGetCmdContent())

    def GetUnGetCmdSize(self):
        return self.fGetUnGetCmdSize()

    def GetCmdContent_Order(self):
        # 订单回报回调
        return self.fGetCmdContent_Order()

    def GetCmdContent_Settlement(self):
        # 结算单确认回调
        return self.fGetCmdContent_Settlement()

    def GetCmdContent_Error(self):
        # 错误信息回调
        return self.fGetCmdContent_Error()

    def GetCmdContent_LoginScuess(self):
        # 登录回调
        return self.fGetCmdContent_LoginScuess()

    def GetCmdContent_Connected(self):
        # 连接成功回调
        return self.fGetCmdContent_Connected()

    def GetCmdContent_ProductGroupMargin(self):
        # 请求查询合约保证金率响应回调
        return self.fGetCmdContent_ProductGroupMargin()

    def GetCmdContent_CommissionRate(self):
        # 请求查询合约手续费率响应回调
        return self.fGetCmdContent_CommissionRate()
